﻿use async_trait::async_trait;
use rand::{seq::SliceRandom, Rng};
use std::time::Instant;
use yansi::Paint;

use crate::data::PACKAGES_LIST;
use crate::io::{csleep, dprint, newline};
use crate::{AppConfig, Module};

pub struct Aur;

#[async_trait(?Send)]
impl Module for Aur {
    fn name(&self) -> &'static str {
        "aur"
    }

    fn signature(&self) -> String {
        "yay -S <package>".to_string()
    }

    async fn run(&self, appconfig: &AppConfig) {
        let mut rng = rand::thread_rng();
        let chosen = PACKAGES_LIST.choose(&mut rng).unwrap();
        let version = format!(
            "{}.{}.{}-{}",
            rng.gen_range(1..5),
            rng.gen_range(0..10),
            rng.gen_range(0..20),
            rng.gen_range(1..5)
        );

        println!(":: 正在解析依赖关系...");
        csleep(400).await;
        println!(":: 正在查找冲突...");
        csleep(300).await;

        println!(":: 软件包变动 (新安装)：");
        println!("   {}  {}", chosen, version);
        csleep(300).await;

        println!(":: 要安装这些软件包吗？ [Y/n] y");
        csleep(300).await;

        println!(":: 获取软件包源代码...");
        println!("-> 正在克隆 {} 仓库...", chosen);
        println!("Cloning into '{}'...", chosen);
        csleep(1000).await;

        println!(":: 正在运行 pre-build()...");
        csleep(500).await;

        println!(":: 正在运行 build()...");
        csleep(400).await;

        println!(
            "==> 正在构建软件包 {} {} (2025年06月15日 星期日 12:00:00)",
            chosen, version
        );
        csleep(500).await;
        println!("==> 正在检查依赖关系...");
        csleep(400).await;
        println!("==> 获取源码...");
        csleep(300).await;
        println!("==> 正在准备构建...");
        csleep(400).await;
        println!("==> 正在编译...");
        csleep(1000).await;
        println!("==> 正在打包...");
        csleep(600).await;
        println!("==> 正在生成 .PKGINFO 文件...");
        csleep(300).await;
        println!("==> 正在清理临时文件...");
        csleep(300).await;

        println!("==> 完成构建：{} {}", chosen, version);
        csleep(400).await;

        println!(":: 正在安装软件包...");
        csleep(800).await;

        let elapsed = Instant::now().elapsed().as_secs_f32();
        dprint(
            format!(
                "{:>12} {} {} in {:.2} secs",
                Paint::green("已完成").bold(),
                chosen,
                version,
                elapsed
            ),
            0,
        )
        .await;
        newline().await;
        if appconfig.should_exit() {
            return;
        }
    }
}
